	package resources;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.nio.CharBuffer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.WindowConstants;
import javax.swing.border.TitledBorder;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableModel;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import DataTransfer.DefaultDataTransportConnector;
import DataTransfer.DefaultDataTransporter;
import DataTransfer.InputStreamEvent;
import DataTransfer.InputStreamListener;
import DataTransfer.InterfaceDataTransporter;
import cii_lib.CCII_ACCESS_INTERF;
import cii_lib.CII_Tree_Vectors;
import cii_lib.CIIdata;

/**
 * @author alek
 *
 */
@SuppressWarnings("serial")
public class AdvancedView extends JFrame {
	
	private static final Logger log = LoggerFactory
			.getLogger(AdvancedView.DisplayType.class);
	private enum DisplayType{BIN,U2,DEC,HEX,OCT,ASCII};
	private enum CellState{CACHE,MODIFIED,READ,WRITTEN};
	private boolean fillToSize=false; 
		
	public class AdvancedInterfaceTablePanel extends JPanel {
		private class AVCellEditor extends DefaultCellEditor {
			JFormattedTextField tf;

		    public AVCellEditor() {
		    	super(new JFormattedTextField());
		    	tf=(JFormattedTextField)super.getComponent();
		    	tf.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),"check");
		    	tf.getActionMap().put("check", new AbstractAction() {
		    		public void actionPerformed(ActionEvent e) {
		    			stopCellEditing();
		    		}
		    	});
		    							
			}
		    
		    public Component getTableCellEditorComponent(JTable table,
		            Object value, boolean isSelected,
		            int row, int column) {
		        JFormattedTextField ftf =
		            (JFormattedTextField)super.getTableCellEditorComponent(
		                table, value, isSelected, row, column);
		        
		        if(value instanceof Integer)
		        {
		        	tf.setValue(value);
		        	ftf.setText(parseIntByDisplay((Integer)value));
		        }
		        return ftf;
		    }

			public Object getCellEditorValue() {
				return tf.getValue();
		    }
			
			public Integer parseValue(String txt) throws IllegalArgumentException
			{
				Integer val=null;
				if(display==DisplayType.BIN || display==DisplayType.U2) {if(txt.length()>data.getCellSize()) throw new IllegalArgumentException(txt+" is too long for "+data.getCellSize());} 
				else if(display==DisplayType.HEX) {if(txt.length()>data.getCellSize()/4) throw new IllegalArgumentException(txt+" is too long for "+data.getCellSize());}
				else if(display==DisplayType.DEC) {if(txt.length()>data.getCellSize()/3) throw new IllegalArgumentException(txt+" is too long for "+data.getCellSize());}
				else if(display==DisplayType.OCT) {if(txt.length()>data.getCellSize()/3) throw new IllegalArgumentException(txt+" is too long for "+data.getCellSize());}
				else if(display==DisplayType.ASCII) {if(txt.length()>(data.getCellSize()/8)) throw new IllegalArgumentException(txt+" is too long for "+data.getCellSize());}
				
				if(display==DisplayType.BIN) val=Integer.valueOf(txt, 2);
				else if(display==DisplayType.HEX) val=Integer.valueOf(txt, 16); 
				else if(display==DisplayType.DEC) val=Integer.valueOf(txt, 10);
				else if(display==DisplayType.OCT) val=Integer.valueOf(txt, 8);
				else if(display==DisplayType.U2) 
				{
					val=Integer.valueOf(txt, 2);
					val-=1;
					val+= (int)Math.pow(2, data.getCellSize());
				} else if(display==DisplayType.ASCII)
				{
					int v=0;
					for(int i=0;i<txt.length();i++)
					{
						int c=(int)txt.charAt(txt.length()-i-1);
						v+=c*Math.pow(256,i);
					}
					val=v;
				}

				return val;
			}
			
		    public boolean stopCellEditing() {
		    	Integer val=null;
		    	try{
		    	val=parseValue(tf.getText());
		    	}catch(Exception e)
		    	{
		    		Toolkit.getDefaultToolkit().beep();
		    	}
		    	if(val!=null) tf.setValue(val);
		    		
		        return super.stopCellEditing();
		    }
		}

		private class AVCellRender extends DefaultTableCellRenderer 
		{
			public final Color cachedColor=new Color(220,220,220);
			public final Color modifiedColor=new Color(255,220,220);
			public final Color readColor=new Color(220,255,220);
			public final Color writtenColor=new Color(180,255,180);
			private Color bckg;
			CellState[][] states;
			
			public void setSelectedBackground(Color color)
			{
				bckg=color;
			}
			
			public void setTableSize(int width,int height)
			{
				states=new CellState[width][height];
			}
			
			public void setState(int row,int column,CellState state)
			{
				states[column][row]=state;
			}
			
			public void setState(List<Rectangle> areas,CellState state)
			{
				Iterator<Rectangle> it=areas.iterator();

				while(it.hasNext())
				{
					Rectangle rct=it.next();
					for(int row=rct.y;row<rct.y+rct.height;row++)
						for(int column=rct.x;column<rct.x+rct.width;column++)
								states[column][row]=state;
				}
			}
			
		    public Component getTableCellRendererComponent
		       (JTable table, Object value, boolean isSelected,
		       boolean hasFocus, int row, int column) 
		    {
		    	Component cell = super.getTableCellRendererComponent
		           (table, value, isSelected, hasFocus, row, column);
		    	
		    	Color newcolor;
		    	if(value!=null)
		    	{
		    		if(states[column][row]==null || states[column][row].equals(CellState.CACHE))
		    			newcolor=cachedColor;
		    		else if(states[column][row].equals(CellState.MODIFIED))
		    			newcolor=modifiedColor;
		    		else if(states[column][row].equals(CellState.READ))
		    			newcolor=readColor;
		    		else if(states[column][row].equals(CellState.WRITTEN))
		    			newcolor=writtenColor;
		    		else {return cell;}
		    	} else newcolor=Color.WHITE; 
		    		
		    	if(isSelected)
		    	{
		    		newcolor=new Color(newcolor.getRed()*bckg.getRed()/255,
		    				newcolor.getGreen()*bckg.getGreen()/255,
		    				newcolor.getBlue()*bckg.getBlue()/255
		    				);
		    	}
		    	
		    	cell.setBackground(newcolor);
		    	if(cell instanceof JLabel)
		    	{
		    		JLabel lbl=(JLabel)cell;
		    		if(value instanceof Integer)
		    		{
		    			
		    			lbl.setText(parseIntByDisplay((Integer)value));
		    		};
		    	}
		    	return cell;
		    }
		}
		
		
		private JScrollPane jScrollPane1;
		private JTable jTable1;
		private JPanel jMainPanel;
		//private JPanel jPanelNav;
	//	private Dimension sizes;
		private XmlInterfaceData data;
		private CII_Tree_Vectors iface;
		private JPopupMenu popupMenu;
		JMenuItem mnuRead,mnuCopy,mnuPaste,mnuWrite,mnu5;
		private List<Rectangle> selection;
		private Boolean isUserInput;
//		private AccessMode access;
		private CCII_ACCESS_INTERF inter;
		private AVCellRender cellRenderer;
		private AVCellEditor cellEditor;
		private Map<AdvancedInterfaceTablePanel,InterfaceDataTransporter> mDataTransporters;
	//	private Map<InterfaceDataTransporter,List<Rectangle>> sentRects;
	//	private Map<InterfaceDataTransporter,List<Rectangle>> recvRects;
		private int pasteRow;
		private int pasteCol;
		
		public int selectionMinRow;
		public int selectionMinCol;
		private DisplayType display=DisplayType.DEC;
		public AdvancedInterfaceTablePanel()
		{
			super();
			initGUI();
			data=new XmlInterfaceData();
			mDataTransporters=new HashMap<AdvancedInterfaceTablePanel,InterfaceDataTransporter>();
			isUserInput=true;
		}
		
		private String parseIntByDisplay(Integer val)
		{
			String txt;
					    			
			if(this.display==DisplayType.HEX) 
			{
					txt=String.format("%X",val);
					if(fillToSize)
						for(int i=txt.length();i<data.getCellSize()/4;i++)
							txt="0"+txt;
			}
			
			else if(display==DisplayType.BIN) 
			{
				txt=Integer.toBinaryString(val);
				if(fillToSize)
					for(int i=txt.length();i<data.getCellSize();i++)
							txt="0"+txt;

					
			} else if(display==DisplayType.U2)
			{
				int num=(int) Math.pow(2, data.getCellSize());
				num-=val;
				num+=1;
				txt=Integer.toBinaryString(num);
				if(fillToSize)
					for(int i=txt.length();i<data.getCellSize();i++)
						txt="0"+txt;
			}
			else if(display==DisplayType.ASCII)
			{
				int reszta;
				int ile=0;
				txt=new String();
				while(val>0)
				{
					reszta=val%256;
					val=val/256;
					txt=(char)reszta+txt;
					ile++;
				}
				
				if(fillToSize)
				for(int i=ile;i<data.getCellSize()/8;i++)
				{
					txt=((char)0)+txt;
				}
			}
			else txt=String.format("%d",val);

			return txt;
		}
		
		public void setDisplay(DisplayType dsp)
		{
			display=dsp;
			jTable1.repaint();
		}
		
		public void initGUI()
		{
			setLayout(new BorderLayout());
			jMainPanel=new JPanel();
			jMainPanel.setLayout(new BorderLayout());
			add(jMainPanel,BorderLayout.CENTER);
			jScrollPane1 = new JScrollPane();
			jMainPanel.add(jScrollPane1,BorderLayout.CENTER);
			jTable1 = new JTable();
			jScrollPane1.setViewportView(jTable1);
			isUserInput=false;
			{
				JMenuBar uppermenubar=new JMenuBar();
				JMenu uppermenu=new JMenu("View");
				ButtonGroup group = new ButtonGroup();
				final JRadioButtonMenuItem mnuBin=new JRadioButtonMenuItem("Binary");
				final JRadioButtonMenuItem mnuDec=new JRadioButtonMenuItem("Decimal");
				final JRadioButtonMenuItem mnuHex=new JRadioButtonMenuItem("Hexadecimal");
				final JRadioButtonMenuItem mnuU2=new JRadioButtonMenuItem("U2");
				final JRadioButtonMenuItem mnuASCII=new JRadioButtonMenuItem("ASCII");
				JSeparator sep=new JSeparator();
				final JCheckBoxMenuItem mnuFill=new JCheckBoxMenuItem("Fill to Data Width");
				mnuFill.setState(fillToSize);
								
				uppermenu.add(mnuBin);
				uppermenu.add(mnuDec);
				uppermenu.add(mnuHex);
				uppermenu.add(mnuU2);
				uppermenu.add(mnuASCII);
				uppermenu.add(sep);
				uppermenu.add(mnuFill);
				group.add(mnuBin);
				group.add(mnuDec);
				group.add(mnuHex);
				group.add(mnuU2);
				group.add(mnuASCII);
				mnuHex.setSelected(true);
				ActionListener al=new ActionListener(){
					public void actionPerformed(ActionEvent arg0) {
						Object source=arg0.getSource();
						if(source==mnuBin) setDisplay(DisplayType.BIN); 
						else if(source==mnuDec) setDisplay(DisplayType.DEC);
						else if(source==mnuHex) setDisplay(DisplayType.HEX);
						else if(source==mnuU2) setDisplay(DisplayType.U2);
						else if(source==mnuASCII) setDisplay(DisplayType.ASCII);
						else if(source==mnuFill)
						{
							if(mnuFill.getState()) fillToSize=true;
							else fillToSize=false;
							jTable1.repaint();								
						}
					}
				};
				mnuBin.addActionListener(al);
				mnuDec.addActionListener(al);
				mnuHex.addActionListener(al);
				mnuU2.addActionListener(al);
				mnuASCII.addActionListener(al);
				mnuFill.addActionListener(al);
								
				uppermenubar.add(uppermenu);
				add(uppermenubar,BorderLayout.PAGE_START);
			}
			
			{
				popupMenu=new JPopupMenu();
				mnuRead=new JMenuItem("Read Selection");
				mnuWrite=new JMenuItem("Write Selection");
				JSeparator separator=new JSeparator(); 
				mnuCopy=new JMenuItem("Copy Selection");
				mnuPaste=new JMenuItem("Paste");
				popupMenu.add(mnuRead);
				popupMenu.add(mnuWrite);
				popupMenu.add(separator);
				popupMenu.add(mnuCopy);
				popupMenu.add(mnuPaste);
				mnuRead.setEnabled(true);
				mnuCopy.setEnabled(true);
				mnuPaste.setEnabled(false);

				isUserInput=false;
				/*
				jTableViewport.addChangeListener(new ChangeListener(){
				
					public void stateChanged(ChangeEvent e) {
						Rectangle rct=jTableViewport.getViewRect();
						
						Point upperleft=new Point(rct.x,rct.y);
						Point lowerright=new Point(rct.x+rct.width-1,rct.y+rct.height-1);
						viewRect.x=jTable1.columnAtPoint(upperleft);
						viewRect.y=jTable1.rowAtPoint(upperleft);

						if(lowerright.x>=jTable1.getWidth())
							viewRect.width=jTable1.getColumnCount()-viewRect.x;
						else viewRect.width=jTable1.columnAtPoint(lowerright)-viewRect.x+1;
						
						if(lowerright.y>=jTable1.getHeight())
							viewRect.height=jTable1.getRowCount()-viewRect.y;
						else viewRect.height=jTable1.rowAtPoint(lowerright)-viewRect.y+1;
						//log.debug(viewRect.toString());
						presentData(viewRect);
					}
				
				});
				*/
				final AdvancedInterfaceTablePanel thisFrame=this;
				
				mnuRead.addActionListener(new ActionListener(){
					public void actionPerformed(ActionEvent arg0) {
						getSelection();
						read(selection);
					}
				});
							
				mnuWrite.addActionListener(new ActionListener(){
					public void actionPerformed(ActionEvent arg0) {
						getSelection();
						write(selection);
					}
				});
				
				mnuCopy.addActionListener(new ActionListener(){
					public void actionPerformed(ActionEvent arg0) {
						getSelection();
						AdvancedView.setLastCopy(selection, thisFrame);
						
					}
				});
				
				mnuPaste.addActionListener(new ActionListener(){
					public void actionPerformed(ActionEvent arg0) {
						InterfaceDataTransporter trnsClient;
						if(mDataTransporters.containsKey(AdvancedView.getLastCopyPanel()))
						{
							trnsClient=mDataTransporters.get(AdvancedView.getLastCopyPanel());
							log.debug("bylo");
						} else
						{
							trnsClient=new DefaultDataTransporter();
							InterfaceDataTransporter trnsServer=new DefaultDataTransporter();
							DefaultDataTransportConnector cnctr=new DefaultDataTransportConnector();
							cnctr.setClient(trnsClient);
							cnctr.setServer(trnsServer);
							AdvancedInterfaceTablePanel tbl=AdvancedView.getLastCopyPanel();
							tbl.setTransporter(trnsServer,thisFrame);
							setTransporter(trnsClient,tbl);
							try {
								cnctr.connect();
							} catch (IOException e) {
								log.error("", e);
							}
						}
							String req="REQUEST ";
							Iterator<Rectangle> rit=AdvancedView.getLastCopy().iterator();
							while(rit.hasNext())
							{
								Rectangle rct=rit.next();
								req+=rct.x+" "+rct.y+" "+rct.width+" "+rct.height+" ";
							}
							trnsClient.send(req);
							trnsClient.flush();
							
						}
					
				});
			}
			
			jTable1.addMouseListener(new MouseAdapter() {
				public void mouseClicked(MouseEvent e) {
                	if (e.isPopupTrigger()) {
                		if(AdvancedView.getLastCopy()!=null) mnuPaste.setEnabled(true);
                			else mnuPaste.setEnabled(false);
                		popupMenu.show(jTable1, e.getX(), e.getY());
                		pasteRow = jTable1.rowAtPoint(e.getPoint());
                		pasteCol = jTable1.columnAtPoint(e.getPoint());
                    }
                }

				public void mouseReleased(MouseEvent e) {
                	if (e.isPopupTrigger()) {
                		if(AdvancedView.getLastCopy()!=null) mnuPaste.setEnabled(true);
            				else mnuPaste.setEnabled(false);
                		popupMenu.show(jTable1, e.getX(), e.getY());
                		pasteRow = jTable1.rowAtPoint(e.getPoint());
                		pasteCol = jTable1.columnAtPoint(e.getPoint());
                		
                    }	
				}});
			
		} 
		
		public void setTransporter(InterfaceDataTransporter trns,AdvancedInterfaceTablePanel panel)
		{
			final InterfaceDataTransporter transport=trns;
			mDataTransporters.put(panel,trns);
			transport.addInputStreamListener(new InputStreamListener() {
				public void dataAvailable(InputStreamEvent evt) {
					String message=evt.getMessage();
					log.debug(message);
					StringTokenizer st = new StringTokenizer(message);
					if(st.hasMoreTokens())
					{
						String token=st.nextToken();
						if(token.equals("REQUEST"))
						{
							List<Rectangle> areas=parseRects(st);
							transport.send("DATA");
							transport.flush();
							try {
								Thread.sleep(10);
							} catch (InterruptedException e) {
								
								log.error("", e);
							}
							data.exportXML(transport.getOutputStream(), areas);
							transport.send("END");
							transport.flush();
							
						} else if(token.equals("DATA"))
						{
							PipedInputStream pipin=new PipedInputStream();
							Thread fix=new fixthread(evt.getInputStream(),pipin,Thread.currentThread()); //bo parser musi miec zamkniety stream
							fix.start();
							XmlInterfaceData tmp=new XmlInterfaceData();
							try {
								tmp.importXML(pipin);
							} catch (Exception e) {
								log.error("", e);
							}
							pasteData(tmp,AdvancedView.getLastCopy(),pasteCol,pasteRow);
						}
					}
				}
			});
		}
		
		private class fixthread extends Thread
		{
			Thread tparent;
			PipedOutputStream pipout;
			InputStream in;
			
			public fixthread(InputStream instream,PipedInputStream pipin,Thread parent)
			{
				tparent=parent;
				in=instream;
				try {
					pipout=new PipedOutputStream(pipin);
				} catch (IOException e) {
					log.error("", e);
				}
				
			}
			
			public void run()
			{
				BufferedReader rdr=new BufferedReader(new InputStreamReader(in));
				BufferedWriter wrt=new BufferedWriter(new OutputStreamWriter(pipout));
				CharBuffer cb = CharBuffer.allocate(1024);

				int chars;
				try {
					cb.mark();
					while((chars=rdr.read(cb))!=-1)
					{
						cb.rewind();
						String str,end;
						
						end=cb.subSequence(chars-4, chars).toString();
						if(end.equals("END\n"))
						{
							if(chars>4)
							{
								str=cb.subSequence(0, chars-4).toString();
								wrt.write(str);
								wrt.flush();
								log.debug(str);
							}
							cb.mark();
							break;
						} else 
						{
							str=cb.subSequence(0, chars).toString();
							wrt.write(str);
							wrt.flush();
							log.debug(str);
							cb.mark();
						}
					}

					pipout.close();
				} catch (IOException e) {
					log.error("", e);
				}
			}
		}
		
		private void pasteData(XmlInterfaceData dta,List<Rectangle> areas,int x,int y)
		{
			if(areas.size()<1) return;
			Iterator<Rectangle> rit=areas.iterator();
			Iterator<Object> dit=dta.getData(areas).iterator();
			int mincol=areas.get(0).x;
			int minrow=areas.get(0).y;
			while(rit.hasNext())
			{
				Rectangle rct=(Rectangle)rit.next();
				
				for(int row=rct.y;row<rct.y+rct.height;row++)
					for(int col=rct.x;col<rct.x+rct.width;col++)
					{
						Object obj=dit.next();
						int trow=row-minrow+y;
						int tcol=col-mincol+x;
						if(trow<this.getInterfaceData().getSize().height && tcol<this.getInterfaceData().getSize().width)
							data.setValueAt(obj, trow, tcol);
					}
								
				
			}
		}
		
		private List<Rectangle> parseRects(StringTokenizer st)
		{
			Vector<Rectangle> tmp= new Vector<Rectangle>();
			while(st.hasMoreElements())
			{
				Rectangle rct=new Rectangle();
				rct.x=Integer.parseInt(st.nextToken());
				rct.y=Integer.parseInt(st.nextToken());
				rct.width=Integer.parseInt(st.nextToken());
				rct.height=Integer.parseInt(st.nextToken());
				tmp.add(rct);
			}
			return tmp;
		}
		
		public CII_Tree_Vectors getInterface()
		{
			return iface;
		}
		
		public XmlInterfaceData getInterfaceData()
		{
			return data;
		}
		
//		public AccessMode getAccessMode()
//		{
//			return access;
//		}
//		
//		public void setAccessMode(AccessMode acmode)
//		{
//			access=acmode;		
//			jPanelAccess.setBorder(BorderFactory.createTitledBorder(null, "Access "+access.getModeName(), TitledBorder.LEADING, TitledBorder.TOP));
//		}
		
		public void setTable(CII_Tree_Vectors interf)
		{
			int x = new Integer(interf.get(4));
			int y = new Integer(interf.get(5));

			iface=interf;
			jMainPanel.setBorder(BorderFactory.createTitledBorder(null, interf.get(1), TitledBorder.LEADING, TitledBorder.TOP));
			{
				TableModel jTable1Model=data;
				
				jTable1.setModel(jTable1Model);

				cellRenderer=new AVCellRender();
				cellRenderer.setTableSize(y,x);
				cellRenderer.setSelectedBackground(jTable1.getSelectionBackground());
				jTable1.setDefaultRenderer(Object.class,cellRenderer );
				
				cellEditor=new AVCellEditor();
				jTable1.setDefaultEditor(Object.class, cellEditor);				
				
				jTable1.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
				jTable1.setColumnSelectionAllowed(true);
				jTable1.setAutoResizeMode(0);
				jTable1.setRowSelectionAllowed(true);
	
				Rule rowView = new Rule(Rule.VERTICAL, false);if (x>=10) {
					int ilC= 1,tmp;
//					Math.pow(a, b)
					while (true){
						tmp=x/((int)Math.pow(10, ilC));
						if (tmp==0) break;
						ilC++;
					}
					Rule.SIZE = 12*ilC;
				}
				else Rule.SIZE=16;
				rowView.Adjust(jTable1);
				
				
				
				jScrollPane1.setRowHeaderView(rowView);
				data.addTableModelListener(new TableModelListener(){
					public void tableChanged(TableModelEvent e) {
						synchronized(isUserInput)
						{
							if(isUserInput)
							{
								int x=e.getColumn();
								int y=e.getFirstRow();
								Object value=data.getValueAt(y, x);
								if(value!=null)
								log.debug("User typed x("+Integer.toString(x)+") y("+Integer.toString(y)+"): "+value.toString());
								cellRenderer.setState(y,x, CellState.MODIFIED);
							}
						}
					}

					
				});
			}
			if(y<8)
				setPreferredSize(new Dimension(y*50,0));
			else setPreferredSize(new Dimension(600,0));
			
			setMinimumSize(new Dimension(200,200));
//			pack();
		}
		
		public void setData(XmlInterfaceData dta)
		{
			data=dta;
		}
		
		public void setInterfaceAccess(CCII_ACCESS_INTERF inter) {
			this.inter=inter;
		}
		public CCII_ACCESS_INTERF getIntercafeAccess() {
			return inter;
		}
				
		private void read(List<Rectangle> areas)
		{
//			CIIdata Word=new CIIdata(iface.toInt(3));
//		    CIIdata Area=new CIIdata(iface.toInt(3));
//		    CIIdata Bits=new CIIdata(iface.toInt(3));
//		    CIIdata a=new CIIdata(iface.toInt(3));
//
//		    try {
//			    Iterator<Rectangle> it=areas.iterator();
//			    access.Connect();
//			    while(it.hasNext())
//				{
//			    Rectangle rct=it.next();
//				for(int row=rct.y;row<rct.y+rct.height;row++)
//					for(int column=rct.x;column<rct.x+rct.width;column++)
//					{
//				
//				if (iface.isWord()) {
//					a=access.readWord(iface.toInt(3), 
//							Word.GetWidth(),iface.toInt(4), 
//												iface.toInt(5), 
//												iface.toInt(7),
//												row, 
//												column, 
//												Word);
//						
//				
//				}
//				if (iface.isArea()) {
//					a=access.readArea(iface.toInt(3), 
//							Area.GetWidth(),iface.toInt(4), 
//												iface.toInt(5), 
//												iface.toInt(7),
//												row, 
//												column, 
//												Area); 
//				
//				}
//				if (iface.isBits()) {
//					a=access.readBit(iface.toInt(3), 
//							Bits.GetWidth(),iface.toInt(4), 
//												iface.toInt(5), 
//												iface.toInt(7),
//												row, 
//												column,
//												iface.toInt(8),
//												Bits);
//					}
//					data.setValueAt((Integer)(int)a.GetValue(),row, column);
//					cellRenderer.setState(row, column, CellState.READ);
//					}
//				}
//			    access.Disconnect();
//			} catch (AccessModeException e) {
//				log.error("", e);
//				return;
//			}
			CIIdata data= new CIIdata(getIntercafeAccess().Width());
			getIntercafeAccess().Read(jTable1.getSelectedRow(), jTable1.getSelectedColumn(), data);// privInt.GetItem().Address
			log.debug("adv view: "+ data.GetHex());
			jTable1.setValueAt(data.GetValue(), jTable1.getSelectedRow(), jTable1.getSelectedColumn());
			log.debug("read");
			jTable1.repaint();
		}
		
		private void write(List<Rectangle> areas)
		{
//			CIIdata Word=new CIIdata(iface.toInt(3));
//		    CIIdata Area=new CIIdata(iface.toInt(3));
//		    CIIdata Bits=new CIIdata(iface.toInt(3));
//
//		    try {
//			    Iterator<Rectangle> it=areas.iterator();
//			    access.Connect();
//			    while(it.hasNext())
//				{
//			    Rectangle rct=it.next();
//				for(int row=rct.y;row<rct.y+rct.height;row++)
//					for(int column=rct.x;column<rct.x+rct.width;column++)
//					{
//						Integer val=(Integer)data.getValueAt(row,column);
//						
//											
//				if (iface.isWord()) {
//					Word.SetValue((long)val);
//					access.writeWord(iface.toInt(3), 
//							Word.GetWidth(),iface.toInt(4), 
//												iface.toInt(5), 
//												iface.toInt(7),
//												0, 
//												0, 
//												Word);
//						
//				
//				}
//				if (iface.isArea()) {
//					Area.SetValue(val);
//					access.writeArea(iface.toInt(3), 
//							Area.GetWidth(),iface.toInt(4), 
//												iface.toInt(5), 
//												iface.toInt(7),
//												row, 
//												column, 
//												Area); 
//				
//				}
//				if (iface.isBits()) {
//					Bits.SetValue(val);
//					access.writeBit(iface.toInt(3), 
//							Bits.GetWidth(),iface.toInt(4), 
//												iface.toInt(5), 
//												iface.toInt(7),
//												0, 
//												0,
//												iface.toInt(8),
//												Bits);
//					}
//					cellRenderer.setState(row, column, CellState.WRITTEN);
//					}
//				}
//			    
//			    access.Disconnect();
//			} catch (AccessModeException e) {
//				log.error("", e);
//				return;
//			}
			log.debug("write");
			Long o= new Long(0);
			 try {
				o = new Long((""+jTable1.getValueAt(jTable1.getSelectedRow(),jTable1.getSelectedColumn())).trim());	
			 } catch (NumberFormatException e) {
				log.debug("Value discarded - must be long");
			 }
			 CIIdata data= new CIIdata(getIntercafeAccess().Width(),o);
			 getIntercafeAccess().Write(jTable1.getSelectedRow(), jTable1.getSelectedColumn(), data);
			
		}
		
		private void getSelection()
		{
		    int rowIndexStart = jTable1.getSelectedRow();
	        int rowIndexEnd = jTable1.getSelectionModel().getMaxSelectionIndex();
	        int colIndexStart = jTable1.getSelectedColumn();
	        int colIndexEnd = jTable1.getColumnModel().getSelectionModel().getMaxSelectionIndex();
	        selection=new Vector<Rectangle>();
	        selectionMinRow=rowIndexStart;
			selectionMinCol=colIndexStart;
	        for (int c=colIndexStart; c<=colIndexEnd; c++) {
	        	for (int r=rowIndexStart; r<=rowIndexEnd; r++) {
	                    if (jTable1.isCellSelected(r, c)) {
	    				{
	    					boolean niebylo=true;
	    					Iterator<Rectangle> it=selection.iterator();
	    					while(it.hasNext())
	    					{
	    						Rectangle re=it.next();
	    						//if(re.contains(new Point(r,c)))
	    						if(c>=re.x && c<=re.getMaxX() &&r>=re.y && r<=re.getMaxY())	{
	    							niebylo=false;
	    							break;
	    						}
	    					}
	    					if(niebylo)
	    					{
		    					int width=0;
		    					int height=1;
		    					boolean niee=false;
		    					for(int xx=c;xx<=colIndexEnd;xx++)
		    					{
		    						if(jTable1.isCellSelected(r, xx)) width++;
		 
		    						else break;
		    					}
		    					
		    					for(int yy=r+1;yy<=rowIndexEnd;yy++)
		    					{
		    						for(int xx=c;xx<=colIndexEnd && xx<c+width;xx++)
		    						{
		    							if(!(jTable1.isCellSelected(yy, xx))) {niee=true;break;}
		    						}
		    						if(niee) break;
		    						else height++;
		    					}
		    					Rectangle tmp=new Rectangle(c,r,width,height);
		    					c+=width-1;
		    				
		    					selection.add(tmp);
		    				}
		    			}
		            }
	        	}
	        }
	        log.debug("Selection ("+selection.size()+") :"+ selection.toString());
	    }

		
	}
	
	private JPanel jMainPanel;
	private JScrollPane jScrollPane1;
	private Map<CII_Tree_Vectors,AdvancedInterfaceTablePanel> mTables;
	private static List<Rectangle> lastCopy=null;
	private static AdvancedInterfaceTablePanel lastCopyPanel=null;
	private int ileTabl=0;
	public static PipedInputStream inStream;
	public static PipedOutputStream outStream;
	
	
	public AdvancedView()
	{
		super();
		mTables=new HashMap<CII_Tree_Vectors,AdvancedInterfaceTablePanel>();
		initGUI();
	}
	
	public AdvancedInterfaceTablePanel addInterface(CII_Tree_Vectors interf,XmlInterfaceData data)
	{
		AdvancedInterfaceTablePanel newTable=new AdvancedInterfaceTablePanel();
		newTable.setData(data);
		newTable.setTable(interf);
		jMainPanel.add(newTable);
		mTables.put(interf,newTable);
		String newTitle=getTitle();
		if(newTitle.length()>0)
			newTitle=newTitle+" & "+interf.get(1);
		else newTitle=new String(interf.get(1));
		setTitle(newTitle);
		setPreferredSize(new Dimension(320*(++ileTabl), 640));
		pack();
		return newTable;
	}
	
	public Set<CII_Tree_Vectors> getInterfaces()
	{
		return mTables.keySet();
	}
	
	public AdvancedInterfaceTablePanel getInterfaceTable(CII_Tree_Vectors interf)
	{
		return mTables.get(interf);
	}
	
	private void initGUI() {
		try {
			{
				jScrollPane1=new JScrollPane();			
				getContentPane().add(jScrollPane1);
				setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
				jMainPanel= new JPanel();
				jMainPanel.setBackground(Color.BLUE);
				jMainPanel.setLayout(new GridLayout(1,0,1,0));
				jScrollPane1.setViewportView(jMainPanel);
				//jScrollPane1.add(jMainPanel);
			}
			{
				this.setPreferredSize(new Dimension(320, 640));
			}
			//pack();
		} catch(Exception e) {
			log.error("", e);
		}
	}
	
	public static void setLastCopy(List<Rectangle> lastcopy,AdvancedInterfaceTablePanel lastcopyPanel)
	{
		lastCopy=lastcopy;
		lastCopyPanel=lastcopyPanel;
	}
	
	public static List<Rectangle> getLastCopy()
	{
		return lastCopy;
	}
	
	public static AdvancedInterfaceTablePanel getLastCopyPanel()
	{
		return lastCopyPanel;
	}
	
	public JPanel getMainPanel() {
		return jMainPanel;
	}
	public JScrollPane getScrollPanel() {
		return jScrollPane1;
	}
}
